package com.miyu.client1.service.book.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.miyu.client1.dao.book.bookDao;
import com.miyu.client1.pojo.Book;
import com.miyu.client1.pojo.book.BookRule;
import com.miyu.client1.service.book.bookService;
import com.miyu.client1.utils.bookUtils.BookCommutils;
import com.miyu.client1.utils.bookUtils.bookSource;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class bookImpl implements bookService {
    private static ExecutorService executorService;
    private static Pattern pattern = Pattern.compile("<a[^>]*href=(\\\"([^\\\"]*)\\\"|\\'([^\\']*)\\'|([^\\\\s>]*))[^>]*>(.*?)</a>");

    @Resource
    private bookDao bookdao;

    @Override
    public JSONArray searchBook(JSONObject ob)  {
        System.out.println("参数"+ob);
        JSONArray ja = new JSONArray();

        //List<Book> books = setDataSource("ddxs", "先", executorService);

        //启用多线程调用所有网站查询聚合数据处理
        ExecutorService exec = Executors.newCachedThreadPool();//工头
        ArrayList<Future<JSONArray>> results = new ArrayList<Future<JSONArray>>();
        JSONObject jo = new JSONObject();

        JSONObject source = bookSource.getSource();
        for (String key : source.keySet()) {
            JSONObject va = source.getJSONObject(key);
            va.put("search",ob.getString("search"));

          //  System.out.println(key + ": " + va);
          //  {"root":"https://www.biquge5200.com","index":"https://www.biquge5200.com/modules/article/search.php?searchkey=","source":"biquge5200","type":"GET"}
            results.add(exec.submit(new queryTask(va)));
        }
      // ja = setDataSource("ddxs", ob.getString("search"), executorService);

        JSONArray jst = new JSONArray();
        for (int i=0;i<results.size();i++){
            try {
                jst.addAll(results.get(i).get());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return jst;
    }

    @Override
    public JSONObject queryBookList(String bookCode, String ddxs) throws Exception {
        JSONArray ja = new JSONArray();
        Pattern pattern = Pattern.compile("<a\\s*href=\"?([\\w\\W]*?)\"?[\\s]*?[^>]>([\\s\\S]*?)(?=</a>)");
        Document document = Jsoup.connect("http://www.ddxs.com/"+bookCode+"/").get();
        Element body = document.getElementById("a_main");
        Elements titleInfo = body.getElementsByClass("bdsub").get(0).getElementsByClass("info");//图书信息
        Elements img = titleInfo.get(0).getElementsByClass("pic");//图片
        Elements book = titleInfo.get(0).getElementsByClass("book");// 图书更新信息

        JSONObject booktitleInfo = new JSONObject();
        for (Element im:img) {
            booktitleInfo.put("imgSrc","http://www.ddxs.com/"+im.getElementsByTag("img").get(0).attr("src"));
        }
        Element btitle =book.get(0).getElementsByClass("btitle").get(0);

      //  booktitleInfo.put("btitle",btitle);
        booktitleInfo.put("bookName",btitle.getElementsByTag("h1").text());
        Element js =book.get(0).getElementsByClass("js").get(0).getElementsByClass("intro").first();
        booktitleInfo.put("bookMark",js.text());

        Element tbody = document.getElementsByTag("tbody").get(1);
        Elements td = tbody.getElementsByTag("td");
        Map<Integer, List<Element>> integerListMap = splitList(td, 1);
        CountDownLatch latch = new CountDownLatch(3);

        List<Element> list  = integerListMap.get(0);
        JSONObject jo = new JSONObject();
        for (Element el:list) {
            Elements elements =  el.select("td");
            if (StringUtils.isBlank(elements.text()))
                continue;
           //  Element  el = list.get(i);
            jo.clear();
            String hre =  el.child(0).attr("href");
            hre = hre.substring(0,hre.lastIndexOf("."));
            String titleName = el.text();
            jo.put("h",hre);
            jo.put("titleName",titleName);
            ja.add(jo.toJSONString());
        }
        JSONObject rs = new JSONObject();
        rs.put("title",booktitleInfo.toJSONString());
        rs.put("zjList",ja);
        return rs;
    }

    @Override
    public JSONObject readText(String ddxs, String bookCode, String chapterCod) {
        try {
          //  BookCatalogueDto bookCatalogueDto=new BookCatalogueDto();
            JSONObject jo = new JSONObject();
            Document document = Jsoup.connect("http://www.ddxs.com/" + bookCode + "/" + chapterCod + ".html").get();
            Element amain = document.getElementById("amain");
            Elements chapterName =amain.getElementsByTag("h1");
            jo.put("titleName",chapterName.text());//章节名称
            String p = document.select("#contents").html();
            String replace = p.replace("<script>show_htm2();</script> ", "")
                    .replace("/n", "")
                    .replace("<script>show_htm3();</script>", "")
                    .replace("<p>", "<p data-type=\"2\"><span class=\"content-wrap\">")
                    .replace("</p>", "</span></p>");
            jo.put("titleText",replace);//章节内容
            Element footlink = document.getElementById("footlink");
            Elements a = footlink.getElementsByTag("a");
            String href = a.get(0).attr("href").replace("/", "").replace(bookCode, "").replace(".html", "");
            if(!"".equals(href)){
                href= href.replace(".html", "");
                jo.put("titleUp",Integer.parseInt(href));//上一章节
             //   bookCatalogueDto.setUpCode(Integer.parseInt(href));
            }else{
                jo.put("titleUp",null);//上一章节
            }
            href = a.get(2).attr("href").replace("/"+bookCode+"/", "");
            if(!"".equals(href)){
                href= href.replace(".html", "");
                jo.put("titledown",Integer.parseInt(href));//下一章节
               // bookCatalogueDto.setNextCode(Integer.parseInt(href));
            }else{
                jo.put("titledown",null);//下一章节
            }
            jo.put("titleCode",Integer.parseInt(chapterCod));//章节编码
            //bookCatalogueDto.setCatalogueCod(Integer.parseInt(chapterCod));
            jo.put("bookCode",bookCode);//章节编码
            //bookCatalogueDto.setBookCod(bookCod);
            return jo;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public String downloadBook(String bookCode, String bookName) throws Exception {
       JSONObject rs =  queryBookList(bookCode,"ddxs");
       JSONArray data = rs.getJSONArray("zjList");
    Long a = System.currentTimeMillis();
       //多线程调用下载
        ExecutorService exec = Executors.newCachedThreadPool();//工头
        ArrayList<Future<JSONArray>> results = new ArrayList<Future<JSONArray>>();
        List<Future<List>> rst = new ArrayList<>();
        int t=50;//线程数量
        int num = data.size()/t;
        List<Object> collect = null;
        int count = data.size();
            for (int i=0;i<count;i=i+t){
                collect = data.stream().skip(0).limit(t).collect(Collectors.toList());
                if(data.size()>t)
                     data.subList(0,t).clear();
                else
                    data.subList(0,data.size()).clear();
                results.add(exec.submit(new TaskCallable(collect)));
            }
        JSONArray jst = new JSONArray();
       for (int i=0;i<results.size();i++){
           jst.addAll(results.get(i).get());
       }
/*    for (Object js:jst){
        JSONObject s = JSONObject.parseObject(js.toString());
       // System.out.println("序列"+s.getString("num"));
    }*/

        String sysPath = System.getProperty("user.dir");
        String tempPath = "/temp/bookDowntemmp/";
        System.out.println("系统路径"+System.getProperty("user.dir"));

        File file = new File(sysPath+tempPath);
        if(!file.exists()){
            file.mkdirs();
        }

       String titleName = bookName+".txt";
        File writename = new File(sysPath+tempPath+titleName);
        writename.createNewFile();
        BufferedWriter out = new BufferedWriter(new FileWriter(writename));
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < jst.size(); i++) {
            JSONObject da = jst.getJSONObject(i);
            str.append(da.getString("titleName"));
            out.write(str.toString());
            out.write("\r\n");
            str.setLength(0);
            str.append(da.getString("text"));
            out.write(str.toString());
            out.write("\r\n");
        }
            out.close();
        Long b = System.currentTimeMillis();
        System.out.println("耗时长:"+(b-a)/1000);
        System.out.println("rs>>>>>>>>>>>>>"+sysPath+tempPath+titleName);

        return sysPath+tempPath+titleName;
    }

    @Override
    public JSONArray queryBookRuleList() {
        List<BookRule> all = bookdao.findAll();
        JSONArray jsonArray= JSONArray.parseArray(JSONObject.toJSONString(all));
        return jsonArray;
    }

    @Override
    public JSONObject saveOrupdate(JSONObject param) {
        System.out.println("保存数据参数"+param);
        //StudentList stuList = (StudentList) JSONToObj(objList.toString(), StudentList.class);
        BookRule br =      param.toJavaObject(BookRule.class);
        br.setBookId(BookCommutils.getUUID());
        BookRule bookRule = bookdao.saveAndFlush(br);
        System.out.println("baocun");
        return null;
    }

    public static  <T> Map<Integer, List<T>> splitList(List<T> t, int num) {
        Map<Integer, List<T>> subList = new HashMap<>(num);
        int num1 = (int) Math.floor(t.size() / num);
        for (int i = 0; i < num; i++) {
            subList.put(i, t.subList(i * num1, (i + 1) * num1));
            if (i == num - 1) {
                subList.put(i, t.subList(i * num1, t.size()));
            }
        }
        return subList;
    }

    public static JSONArray setDataSource(String dataSource, String key, ExecutorService executorService) {
        //BookList.executorService = executorService;
        try {
          //  Map<String, List<String>> dataSource1 = DataSource.getDataSource();
         //   String url = dataSource1.get(dataSource).get(0);
            String url = "http://www.ddxs.com/search.php";
            String[] split = url.split("--");
            return getBookList(key, url, "get");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static JSONArray getBookList(String key, String url, String way) {
        List<Book> bookDtos = null;
        JSONArray ja = new JSONArray();
        try {
            Document document = null;
            if (way.equals("GET")) {
                document = Jsoup.connect(url + key).get();
            } else {
                Connection connect = Jsoup.connect(url);
                connect.data("keyword", key);
                document = connect.post();
            }
            Element element = document.select("tbody").get(0);
            Elements trs = element.getElementsByTag("tr");
            List<Element> trss = trs.stream().filter(element1 -> !element1.text().isEmpty()).collect(Collectors.toList());
//            bookDtos = get1(trss, pattern);
            ja = get1(trss, pattern);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ja;
    }

    public static JSONArray get1(List<Element> tbody, Pattern pattern) {
        List<Book> bookDtos = new ArrayList<>(tbody.size());
        JSONArray ja = new JSONArray();

        Map<String, Integer> map = new HashMap<>(10);
        tbody.forEach(tr -> {
            List<Node> nodes = tr.childNodes().stream().filter(node -> !node.toString().trim().isEmpty()).collect(Collectors.toList());
            Elements td = tr.getElementsByTag("td");
            String s1 = nodes.toString();
            for (int i = 0; i < nodes.size(); i++) {
                String node = nodes.get(i).toString();
                if (node.matches("(.*)文章名称(.*)") || node.matches("(.*)书名(.*)")) {
                    map.put("bookName", i);
                    continue;
                }
                if (node.matches("(.*)作者(.*)")) {
                    map.put("author", i);
                    return;
                }
            }
            JSONObject jo = new JSONObject();
            Book book = new Book();
            String href = "";
            String reg = ".*</a>.*";
            if (s1.matches(reg)) {
                Matcher matcher = pattern.matcher(s1);
                if (matcher.find()) {
                    href = matcher.group(1);
                    String nameCode = href.substring(href.lastIndexOf(".com")+5,href.length()-2);
                    if("ascript:void(0)".equals(nameCode)){
                        return;
                    }
                    book.setBookCode(nameCode);
                    jo.put("bookCode",nameCode);
                }
            }
            jo.put("hrefs",href.replace("\"",""));
            jo.put("bookName",td.get(map.get("bookName")).text());
            jo.put("author",td.get(map.get("author")).text());
            book.setBookName(td.get(map.get("bookName")).text());
            book.setBookAuthor(td.get(map.get("author")).text());
            bookDtos.add(book);
            ja.add(jo);
        });
        return ja;
    }
}
